/*
 * F_FatEntries.c
 *
 *  Created on: 04/11/2011
 *      Author: tacho
 */
#include "../../headers/GlobalHeaderPFS.h"
extern uint32_t *fatRegion;
extern pthread_mutex_t mutex_fatRegion;

/*-------------------------------------------------------------------------*/
/**

 */
void agregarEntradasACadenaClusters(tnodoEntrada *colaFrente,tnodoEntrada *colaFin, int valor)
{
	uint32_t entrada;
	tnodoEntrada listaClustersLibres;
	buscarClusters(FAT_LIBRE,&listaClustersLibres,valor);
	while (valor > 0){
		entrada=sacarCola (&listaClustersLibres);
		insertarEntradaOrdenadaACadena(&*colaFrente, entrada);
		valor--;
	}

}

/*-------------------------------------------------------------------------*/
/**
Agrega entradas a una cadena de clusters. (Aclaración: evitar su utilizacion
en la creación de dichas cadenas, debido a posible recorrido hasta el final de la lista
en la insercion de cada elemento. Utilizar para agregar elementos.)
 */
void insertarEntradaOrdenadaACadena(tnodoEntrada *lista, int valor) {

		tnodoEntrada actual=NULL;
		tnodoEntrada nuevo = (tnodoEntrada) malloc(sizeof(struct tnodo));
		nuevo->entrada = valor;
		nuevo->sgte = NULL;

		if (*lista == NULL) {
		// Si la lista está vacía la creo
			fatRegion[valor]=0x0FFFFFFF;
			*lista = nuevo;
	} else {
		actual = *lista;
		// Si es el menor de la lista
		if (actual->entrada > valor) {
			fatRegion[valor] = actual->entrada;
			nuevo->sgte = actual;
			*lista = nuevo;

		} else {
			// Si no, recorro la lista hasta el final o donde debo insertarlo y
			while (actual->sgte != NULL && valor
					>= actual->sgte->entrada) {

				actual = actual->sgte;

			}
			// Asigno los punteros
			nuevo->sgte = actual->sgte;
			actual->sgte = nuevo;
			fatRegion[valor] = fatRegion[actual->entrada];
			fatRegion[actual->entrada]=valor;
			}
		}
	}

/*-------------------------------------------------------------------------*/
/**

 */
void removerEntradasACadenaClusters(tnodoEntrada *colaFrente,tnodoEntrada *colaFin, int valor)
{
	tnodoEntrada actual;
	while (*colaFrente != NULL && valor > 0){
		  actual=*colaFrente;
		  if(*colaFrente != *colaFin){
			  *colaFrente = (*colaFrente)->sgte;
		  }
		  else {
			  *colaFrente =NULL;
			  *colaFin = NULL;
		  };
		  pthread_mutex_lock(&mutex_fatRegion);
		  removerEntradaFat(actual->entrada);
		  pthread_mutex_unlock(&mutex_fatRegion);
		  free(actual);
		  valor--;
	}
}


/*-------------------------------------------------------------------------*/
/**
Reemplaza valor contenido en la entrada correspondiente al clusterAct,
por el contenido del segundo argumento de la funcion. Finaliza con la escritura
del bloque en donde se encuentra dicha fat modificada.
 */
uint32_t reemplazarValorFat(uint32_t clusterAct,uint32_t clusterSgte){
	tBloque bloque;
	uint32_t entradasXBloque=ENTRADASXBLOQUE;
	int32_t nroBloque = obtenerDirEnDiscoDeLaEntradaFat(clusterAct);


	fatRegion[clusterAct]=clusterSgte;
	memcpy(&bloque,&fatRegion[clusterAct - clusterAct % entradasXBloque],TAMANO_BLOQUE);
	pedirEscrituraDeBloque(obtenerDirEnDiscoDeLaEntradaFat(clusterAct),&bloque);
	//pthread_mutex_unlock(&mutex_fatRegion);
	return 1;
}

/*-------------------------------------------------------------------------*/
/**

 */
void removerEntradaFat(uint32_t entrada){
	reemplazarValorFat(entrada,FAT_LIBRE);
}

